package com.merak.rebot.core;

import com.alibaba.fastjson.JSON;
import com.ctg.behavior.utils.CtDateUtils;
import com.merak.rebot.common.PythonStatus;
import com.merak.rebot.python.MerakPythonExecutor;
import com.merak.rebot.utils.FileUtil;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Date;

@Slf4j
@Component
public class MerakPythonEngine {

	@Autowired
	private MerakExecRepository merakExecRepository;
	@Autowired
	private MerakPythonExecutor merakPythonExecutor;

	public PythonStatus doExecutor(String scriptPath, String scriptName) {
		PythonStatus pythonStatus = new PythonStatus();

		// 1. 检查脚本是否已在运行中
		if (null != merakExecRepository.execRepository.get(scriptName)) {
			String python = scriptPath + scriptName + ".status";
			try {
				//如果存在status文件，则删除
				new File(python).deleteOnExit();
				String statusBody = FileUtils.readFileToString(new File(python), StandardCharsets.UTF_8);
				pythonStatus = JSON.parseObject(statusBody, PythonStatus.class);
			} catch (Exception e) {
				log.error(e.getMessage(), e);
			}
			log.info("scriptName is running, status:{}", JSON.toJSONString(pythonStatus));
			return pythonStatus;
		}

		// 2. 标识脚本已在运行中
		merakExecRepository.execRepository.put(scriptName, new Date());

		// 4.生成status文件
		{
			String python = scriptPath + scriptName + ".status";
			pythonStatus.setStartTime(CtDateUtils.dateToString(new Date()));
			pythonStatus.setStatus("running");
			pythonStatus.setName(scriptName);
			try {
				FileUtils.writeStringToFile(new File(python), JSON.toJSONString(pythonStatus), StandardCharsets.UTF_8);
			} catch (IOException e) {
				log.info(e.getMessage(), e);
			}
		}

		// 3. 开线程执行脚本
		Thread pythonRuuner = new Thread(new Runnable() {

			@Override
			public void run() {
				MerakPythonEngine.this.innerExecutor(scriptPath, scriptName);

			}

		});
		pythonRuuner.start();


		return pythonStatus;
	}

	private void innerExecutor(String scriptPath, String scriptName) {
		String status = "done";
		String remark = "执行成功";
		try {
			// 1. 开始执行脚本
			BufferedReader reader = null;
			try {
				Process proc = Runtime.getRuntime().exec("python " + scriptPath + scriptName);
				reader = new BufferedReader(new InputStreamReader(proc.getInputStream()));
				String line = null;
				int lineno = 1;
				while ((line = reader.readLine()) != null) {
					log.info("{}\t{}", lineno, line);
					lineno++;
				}
			} catch (Exception e) {
				status = "fail";
				remark = e.getMessage();
				log.error(e.getMessage(), e);

			} finally {
				try {
					reader.close();
				} catch (Exception e) {
					log.error(e.getMessage(), e);
				}
			}
			long l3 = System.currentTimeMillis();
			log.debug("开始移动脚本文件到新目录");
			try {
				FileUtils.copyFile(new File(scriptPath+scriptName),new File(scriptPath+"history"+File.separator+FileUtil.getBakFileName(scriptName)));
			} catch (IOException e) {
				log.error(e.getMessage(), e);
			}
//			merakPythonExecutor.moveParamFile(scriptPath,scriptName,scriptPath+"history"+File.separator,FileUtil.getBakFileName(scriptName));
			long l4 = System.currentTimeMillis();
			log.debug("移动脚本文件到新目录完成，用时{}",l4-l3);
			log.debug("开始移动脚本参数文件到新目录");
			merakPythonExecutor.moveParamFile(scriptPath,scriptName+".param",scriptPath+"history"+File.separator,FileUtil.getBakFileName(scriptName+".param"));
			long l5 = System.currentTimeMillis();
			log.debug("移动脚本参数文件到新目录完成，用时{}",l5-l4);

			// 2. 更新status文件的执行结果，并把status文件复制到logs
			PythonStatus pythonStatus = null;
			try {
				String statusBody = FileUtils.readFileToString(new File(scriptPath + scriptName + ".status"), StandardCharsets.UTF_8);
				pythonStatus = JSON.parseObject(statusBody, PythonStatus.class);
				pythonStatus.setStatus(status);
				pythonStatus.setRemark(remark);
				pythonStatus.setEndTime(CtDateUtils.dateToString(new Date()));
				pythonStatus.setName(scriptName);
				FileUtils.writeStringToFile(new File(scriptPath + scriptName + ".status"),JSON.toJSONString(pythonStatus), StandardCharsets.UTF_8);
				String logPath = scriptPath + "logs" + File.separator;
				FileUtils.copyFile(new File(scriptPath+scriptName+".status"),new File(logPath+FileUtil.getBakFileName(scriptName+".status")));
//				merakPythonExecutor.moveParamFile(scriptPath,scriptName+".status",logPath,FileUtil.getBakFileName(scriptName+".status"));
//			String logPath = scriptPath + FileUtil.getFileNameNoEx(scriptName) + File.separator + "logs" + File.separator;
//			FileUtils.writeStringToFile(new File(logPath+scriptName+".status"),JSON.toJSONString(pythonStatus), StandardCharsets.UTF_8);
			} catch (Exception e) {
				log.error(e.getMessage(), e);
			}
		}finally {
			merakExecRepository.execRepository.remove(scriptName);
		}



	}

}
